package chan.project.manager;

import chan.project.common.ErrorCode;
import chan.project.exception.BusinessException;
import chan.project.model.dto.travelPlan.Address;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.LifecycleState;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class AmapManager {
    @Value("${gaode.key}")
    private String key;

    class result{
        Map<String,String> map;
        String locationName;
    }
    /**
     * 地址转换为经纬度
     * 注意api在同一时间内连续请求4次以上就会进行限流，所以需要进行逐步发送
     * @param address 地址
     * @return 经纬度
     */
    public Map<String,String> getLonAndLat(String address){
        String locationName = address;
        // 返回输入地址address的经纬度信息, 格式是 经度,纬度
        String queryUrl = "http://restapi.amap.com/v3/geocode/geo?key=" + key + "&address=" + address + "&city=";
        // 高德接口返回的是JSON格式的字符串
        String queryResult = getResponse(queryUrl);
        Map<String, String> map = new HashMap<>();
        JSONObject obj = JSONObject.parseObject(queryResult);
        if (obj.get("status").toString().equals("1")) {
            String geocodes = obj.get("geocodes").toString();
            String geocode = JSONUtil.toList(geocodes, String.class).get(0);
            Address runAddress = JSONUtil.toBean(geocode, Address.class);
            String location = runAddress.getLocation();
            locationName = runAddress.getFormatted_address();
            String[] lonAndLat = location.split(",");
            if (lonAndLat != null && lonAndLat.length == 2) {
                map.put("longitude", lonAndLat[0]);
                map.put("latitude", lonAndLat[1]);
            }
        } else if(obj.get("status").toString().equals("0")){
            log.error("MapErrorMessage"+obj);
            if(obj.get("infocode").equals("10021")){
                log.warn("地图限流，睡眠后进行重试");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                map = getLonAndLat(address);
            }
        }
        else {
            throw new BusinessException(ErrorCode.LOCATION_NAME_ERROR,"地址转换经纬度失败，错误码：" + obj.get("infocode"));
        }
        return map;
    }

    /**
     * 将经纬度getLng， getLat 通过getAMapByLngAndLat方法转换地址
     *
     * @param getLng 经度
     * @param getLat 纬度
     * @return 地址名称
     * @throws Exception
     */
    public String getAMapByLngAndLat(String getLng, String getLat) throws Exception {
        String url;
        try {
            url = "http://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + getLng + ","
                    + getLat + "&key=" + key + "&radius=0&extensions=base";
            String queryResult = getResponse(url); // 高德接品返回的是JSON格式的字符串
            // 将获取结果转为json数据
            JSONObject obj = JSONObject.parseObject(queryResult);
            System.out.println("obj为：" + obj);
            if (obj.get("status").toString().equals("1")) {
                // 如果没有返回-1
                JSONObject regeocode = obj.getJSONObject("regeocode");
                if (regeocode.size() > 0) {
                    // 在regeocode中拿到 formatted_address 具体位置
                    return regeocode.get("formatted_address").toString();
                } else {
                    throw new RuntimeException("未找到相匹配的地址！");
                }
            } else {
                throw new RuntimeException("请求错误！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "-1";
    }

    /**
     * 根据两个定位点的经纬度算出两点间的距离
     *
     * @param startLonLat 起始经纬度
     * @param endLonLat   结束经纬度（目标经纬度）
     * @return 两个定位点之间的距离
     */
    private long getDistance(String startLonLat, String endLonLat) {
        // 返回起始地startAddr与目的地endAddr之间的距离，单位：米
        Long result = 0L;
        String queryUrl = "http://restapi.amap.com/v3/distance?key=" + key + "&origins=" + startLonLat + "&destination=" + endLonLat;
        String queryResult = getResponse(queryUrl);
        JSONObject obj = JSONObject.parseObject(queryResult);
        JSONArray ja = obj.getJSONArray("results");
        JSONObject jobO = JSONObject.parseObject(ja.getString(0));
        result = Long.parseLong(jobO.get("distance").toString());
        System.out.println("距离：" + result);
        return result;
    }

    /**
     * 发送请求
     *
     * @param serverUrl 请求地址
     */
    private String getResponse(String serverUrl) {
        // 用JAVA发起http请求，并返回json格式的结果
        StringBuffer result = new StringBuffer();
        try {
            URL url = new URL(serverUrl);
            URLConnection conn = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
}
